#include "HelperIntersectionRemoval.h"


Operations HelperIntersectionRemoval::getActions(IPuzzle *pz,int nStep)  //获取一个解题操作集合（参数为期望数）
{
    Operations ops;
    int n=0;
    //对每个CellSet里的每一个候选数，观察其出现区段是否全部相同，如果相同，则在同时与这些数格想连接的数格里，不能再出现此候选数
    ICellSets css=pz->getCellSets(CellSet_X);
    ICellSets cssY=pz->getCellSets(CellSet_Y);
    ICellSets cssZ=pz->getCellSets(CellSet_Z);

    css.insert(css.end(),cssY.begin(),cssY.end());
    css.insert(css.end(),cssZ.begin(),cssZ.end());

    for(unsigned int cssid=0;cssid<css.size();++cssid)
    {
        ICellSet *cs=css[cssid];
        ICells cells=cs->getCells();
        //对候选数统计出现的数格
        map<Number,ICells> ncs;
        for(unsigned int cid=0;cid<cells.size();++cid)
        {
            ICell *cell=cells[cid];
            ICandidates cands=cell->getCandidates();
            for(Number cand=LOWER_BOUNDER;cand<=UPPER_BOUNDER;++cand)
            {
                if(cands[cand-1]->getValue()==STA_NORMAL)
                    ncs[cand].push_back(cell);
            }
        }
        if(cs->getType() != CellSet_Z)
        {
            //根据ncs分析是否存在同区候选数(for X,Y . not for Z)
            for(map<Number,ICells>::iterator itor=ncs.begin();itor!=ncs.end();++itor)
            {
                int sec=INVALID_BOUNDER;
                for(unsigned int i=0;i< itor->second.size();++i )
                {
                    ICell *cell=itor->second[i];
                    int s;
                    switch(cs->getType())
                    {
                    case CellSet_X:
                        s=(cell->getPoint().getY()-1)%3;
                        break;
                    case CellSet_Y:
                        s=(cell->getPoint().getX()-1)%3;
                        break;
                    default:
                        throw StringException("Not implement for type is not CellSet_X && Y!");
                    }
                    if(sec!=INVALID_BOUNDER && sec!=s )
                    {
                        sec=INVALID_BOUNDER;
                        break;
                    }
                    sec=s;
                }
                if(sec!=INVALID_BOUNDER)
                {
                    //发现区块，在所在的Z数集里进行排除
                    ICell *cell=itor->second[0];
                    ICellSet *pcs=cell->getCellSet(CellSet_Z);
                    ICells zcells=pcs->getCells();
                    for(unsigned int i=0;i<zcells.size();++i)
                    {
                        bool bFound=false;
                        ICell* pc=zcells[i];
                        for(unsigned int j=0;j<itor->second.size();++j)
                        {
                            if(itor->second[j]==pc)
                            {
                                bFound=true;
                                break;
                            }
                        }
                        if(!bFound)
                        {
                            if(pc->getCandidate(itor->first)==STA_NORMAL)
                            {
                                //发现一个可以由区块排除法排除的候选数
                                Operation op(OperationTagCandidateDelete,nID);
                                string str= cs->toString();
                                str+="只在"+implode(",",getStrings(itor->second))+"有候选数";
                                str+=itor->first;
                                str+=",排除";
                                str+=pc->toString();
                                str+="的该候选数";
                                op.setDesc(str);
                                op.addNumber(itor->first);
                                op.addPoint(pc->getPoint());
                            }
                        }
                    }
                    if(++n >= nStep)
                        return ops;
                }
            }
        }
        else
        {
            //for Z.explode candidate from X or Y!
            for(map<Number,ICells>::iterator itor=ncs.begin();itor!=ncs.end();++itor)
            {
                int sec=INVALID_BOUNDER;
                for(unsigned int i=0;i< itor->second.size();++i )
                {
                    ICell *cell=itor->second[i];
                    int s;
                }

                if(sec!=INVALID_BOUNDER)
                {
                    //发现区块，在所在的Z数集里进行排除
                }
            }
        }
    }
    return ops;
}


